package starfire;

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.event.*;

import java.net.*;
import starfire.ftp.*;
import starfire.gui.siteTree.FtpFileNode;
import starfire.task.*;
import starfire.gui.*;

/**
 * <p>Title: JFtp</p>
 * <p>Description: ftp client</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author starfire
 * @version 1.0
 */

public class FtpSearchFrame extends JFrame {
  JPanel settingPanel = new JPanel();
  JButton stopButton = new JButton();
  JSpinner threadNumSpinner = new JSpinner();
  JLabel endIpLabel = new JLabel();
  JButton loadButton = new JButton();
  JTextField endIpField = new JTextField();
  JButton startButton = new JButton();
  JScrollPane jScrollPane1 = new JScrollPane();
  JLabel startIpLabel = new JLabel();
  JPanel resultPanel = new JPanel();
  JLabel threadNumberLabel = new JLabel();
  JTextField startIpField = new JTextField();
  JButton saveButton = new JButton();
  JPanel panel1 = new JPanel();
  JPanel statusPanel = new JPanel();
  Border border1;
  Border border2;
  Border border3;
  Border border4;
  Border border5;
  TitledBorder titledBorder1;
  Border border6;
  TitledBorder titledBorder2;
  Border border7;
  Border border8;
  BorderLayout borderLayout1 = new BorderLayout();
  JRadioButton autoSaveButton = new JRadioButton();
  JTree resultTree = new JTree();
  JTree detailTree = new JTree();
  java.util.Timer threadTimer = null;
  java.util.Timer autoSaveTimer = null;
  String autoSaveName = null;
  long startTime = 0L;
  long currentTime = 0L;

  Vector threads = new Vector();
  Vector searchResults = new Vector();
  Vector users = new Vector();
  Vector passwords = new Vector();

  JLabel threadLabel = new JLabel();
  Border border9;
  JLabel resultLabel = new JLabel();
  Border border10;
  JLabel currentThreadLabel = new JLabel();
  Border border11;
  JLabel timeoutLabel = new JLabel();
  JSpinner timeoutSpinner = new JSpinner();

  int timeout = -1;
  private boolean stop = false;
  JTextField findField = new JTextField();
  JButton findButton = new JButton();
  Border border12;
  JPanel detailStatusPanel = new JPanel();
  Border border13;
  TitledBorder titledBorder3;
  JScrollPane detailScrollPane = new JScrollPane();
  BorderLayout borderLayout2 = new BorderLayout();
  Border border14;
  JSplitPane splitPane = new JSplitPane();
  Border border15;
  JPopupMenu popMenu = new JPopupMenu();
  JMenuItem downloadItem = new JMenuItem();

  JFtpFrame ftpFrame;

  public FtpSearchFrame(JFtpFrame ftpFrame) {
    this.ftpFrame = ftpFrame;
    try {
      jbInit();
      initSearch();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void initSearch()
  {
    users.add("movie");
    users.add("download");
    passwords.add("movie");
    passwords.add("download");
  }

  private void jbInit() throws Exception {
    border15 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    resultTree.setModel(null);
    resultTree.addMouseListener(new FtpSearchFrame_resultTree_mouseAdapter(this));
    border1 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border2 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border3 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border4 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border5 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    titledBorder1 = new TitledBorder(border5,"Setting");
    border6 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    titledBorder2 = new TitledBorder(border6,"Result");
    border7 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border8 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border9 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border10 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border11 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border12 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    border13 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    titledBorder3 = new TitledBorder(BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151)),"Detail Status");
    border14 = BorderFactory.createEtchedBorder(Color.white,new Color(165, 163, 151));
    settingPanel.setLayout(null);
    settingPanel.setBorder(titledBorder1);
    settingPanel.setDebugGraphicsOptions(0);
    settingPanel.setBounds(new Rectangle(8, 9, 133, 419));
    stopButton.setBounds(new Rectangle(68, 261, 48, 25));
    stopButton.setEnabled(false);
    stopButton.setBorder(null);
    stopButton.setText("stop");
    stopButton.addActionListener(new FtpSearchFrame_stopButton_actionAdapter(this));
    threadNumSpinner.setModel(new SpinnerNumberModel(50,1,1000,10));
    threadNumSpinner.setBounds(new Rectangle(12, 140, 103, 26));
    timeoutSpinner.setModel(new SpinnerNumberModel(-1,-1,15,1));
    endIpLabel.setText("end ip");
    endIpLabel.setBounds(new Rectangle(12, 68, 54, 16));
    loadButton.setBounds(new Rectangle(12, 333, 68, 25));
    loadButton.setBorder(null);
    loadButton.setText("Load");
    loadButton.addActionListener(new FtpSearchFrame_loadButton_actionAdapter(this));
    endIpField.setText("255.255.255.255");
    endIpField.setBounds(new Rectangle(10, 85, 116, 22));
    endIpField.addActionListener(new FtpSearchFrame_endIpField_actionAdapter(this));
    startButton.setBounds(new Rectangle(12, 262, 47, 25));
    startButton.setBorder(null);
    startButton.setText("start");
    startButton.addActionListener(new FtpSearchFrame_startButton_actionAdapter(this));
    jScrollPane1.setBorder(border8);
    startIpLabel.setText("start ip");
    startIpLabel.setBounds(new Rectangle(10, 21, 107, 16));
    resultPanel.setBorder(titledBorder2);
    resultPanel.setBounds(new Rectangle(132, 20, 509, 416));
    resultPanel.setLayout(borderLayout1);
    threadNumberLabel.setText("thread number");
    threadNumberLabel.setBounds(new Rectangle(11, 113, 108, 21));
    startIpField.setText("255.255.255.255");
    startIpField.setBounds(new Rectangle(9, 39, 117, 22));
    saveButton.setBounds(new Rectangle(12, 296, 68, 25));
    saveButton.setEnabled(false);
    saveButton.setBorder(null);
    saveButton.setText("Save");
    saveButton.addActionListener(new FtpSearchFrame_saveButton_actionAdapter(this));
    panel1.setLayout(null);
    statusPanel.setBorder(border9);
    statusPanel.setBounds(new Rectangle(9, 436, 626, 31));
    statusPanel.setLayout(null);
    this.setResizable(false);
    this.setState(Frame.NORMAL);
    this.setTitle("FtpSearch");
    autoSaveButton.setText("Auto save");
    autoSaveButton.setBounds(new Rectangle(13, 228, 111, 25));
    threadLabel.setBorder(null);
    threadLabel.setText("Thread:0/0");
    threadLabel.setBounds(new Rectangle(2, 2, 147, 26));
    resultLabel.setBorder(null);
    resultLabel.setText("Result:0/0");
    resultLabel.setBounds(new Rectangle(157, 3, 203, 26));
    currentThreadLabel.setBorder(null);
    currentThreadLabel.setText("stopped");
    currentThreadLabel.setBounds(new Rectangle(371, 2, 249, 26));
    //resultTree.setFont(new java.awt.Font("Dialog", 0, 12));
    timeoutLabel.setText("Connect timeout");
    timeoutLabel.setBounds(new Rectangle(13, 173, 111, 19));
    timeoutSpinner.setBounds(new Rectangle(12, 198, 103, 26));
    findField.setEnabled(false);
    //findField.setFont(new java.awt.Font("Dialog", 0, 12));
    findField.setText("");
    findField.setBounds(new Rectangle(13, 363, 98, 22));
    findField.addActionListener(new FtpSearchFrame_findField_actionAdapter(this));
    findButton.setBounds(new Rectangle(13, 388, 69, 25));
    findButton.setEnabled(false);
    findButton.setBorder(null);
    findButton.setText("Find File");
    findButton.addActionListener(new FtpSearchFrame_findButton_actionAdapter(this));
    detailStatusPanel.setBorder(titledBorder3);
    detailStatusPanel.setBounds(new Rectangle(497, 20, 140, 415));
    detailStatusPanel.setLayout(borderLayout2);
    detailScrollPane.getViewport().setBackground(Color.white);
    detailScrollPane.setBorder(border14);
    splitPane.setBorder(border15);
    splitPane.setDividerSize(3);
    splitPane.setBounds(new Rectangle(146, 17, 494, 409));
    detailTree.setFont(new java.awt.Font("Dialog", 0, 12));
    downloadItem.setText("download");
    downloadItem.addActionListener(new FtpSearchFrame_downloadItem_actionAdapter(this));
    settingPanel.add(startIpLabel, null);
    settingPanel.add(loadButton, null);
    settingPanel.add(saveButton, null);
    settingPanel.add(startButton, null);
    settingPanel.add(autoSaveButton, null);
    panel1.add(settingPanel, null);
    this.setSize(650,500);
    this.getContentPane().add(panel1, BorderLayout.CENTER);
    statusPanel.add(threadLabel, null);
    settingPanel.add(startIpField, null);
    settingPanel.add(endIpLabel, null);
    settingPanel.add(endIpField, null);
    settingPanel.add(threadNumberLabel, null);
    settingPanel.add(threadNumSpinner, null);
    settingPanel.add(timeoutLabel, null);
    settingPanel.add(timeoutSpinner, null);
    panel1.add(statusPanel, null);
    settingPanel.add(findField, null);
    settingPanel.add(findButton, null);
    settingPanel.add(stopButton, null);
  //  panel1.add(detailStatusPanel, null);
    detailStatusPanel.add(detailScrollPane, BorderLayout.CENTER);
  //panel1.add(resultPanel, null);
    resultPanel.add(jScrollPane1, BorderLayout.CENTER);
    panel1.add(splitPane, null);
    jScrollPane1.getViewport().add(resultTree, null);
    statusPanel.add(currentThreadLabel, null);
    statusPanel.add(resultLabel, null);
    resultTree.setScrollsOnExpand(true);
    resultTree.addTreeExpansionListener(new ExpandTree());
    splitPane.add(resultPanel,JSplitPane.LEFT);
    splitPane.add(detailStatusPanel,JSplitPane.RIGHT);
    splitPane.setDividerLocation(350);
    detailTree.setModel(null);
    this.detailScrollPane.getViewport().add(
        detailTree,BorderLayout.CENTER);
    popMenu.add(downloadItem);
  }

  private DefaultTreeModel createResultTreeModel()
  {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("SearchResult");
    root.setAllowsChildren(true);
    return new DefaultTreeModel(root,true);
  }

  void endIpField_actionPerformed(ActionEvent e) {

  }

  void enableFind()
  {
    findField.setEnabled(true);
    findButton.setEnabled(true);
  }

  void onStart(ActionEvent e) {
    String start = startIpField.getText();
    String end = endIpField.getText();
    if (!SearchTaskManager.getManager().set(start,end))
    {
      JOptionPane.showMessageDialog(this,"Error ip address!","warrning",
                                    JOptionPane.WARNING_MESSAGE);
      return;
    }
    int num = ((Integer)(
        this.threadNumSpinner.getModel().getValue())).intValue();
    startButton.setEnabled(false);
    stopButton.setEnabled(true);
    loadButton.setEnabled(false);
    saveButton.setEnabled(true);
    startIpField.setEditable(false);
    endIpField.setEditable(false);
    this.threadNumSpinner.setEnabled(false);
    this.timeoutSpinner.setEnabled(false);
    resultTree.setModel(createResultTreeModel());
    threads.clear();
    timeout = ((Integer)( this.timeoutSpinner.getValue())).intValue()*1000;
    stop = false;
    startTime = System.currentTimeMillis();
    int i=0;
    for ( ;i<num;i++)
    {
      threads.add(new SearchThread(i));
    }
    threadTimer = new java.util.Timer(true);
    threadTimer.schedule(new CheckThread(),0,500);
    currentThreadLabel.setText(i+" threads started,watting all threads end...");
    if (this.autoSaveButton.isSelected())
    {
      autoSaveTimer = new java.util.Timer(true);
      autoSaveTimer.schedule(new AutoSaveTask(),1000*60,3000*60);
    }
    detailTree.setModel(getThreadTreeModel());
  }

  TreeModel getThreadTreeModel()
  {
    DefaultTreeModel model = null;
    DefaultMutableTreeNode root = new DefaultMutableTreeNode(
        "Search Thread");
    DefaultMutableTreeNode node = null;
    SearchThread thread = null;
    for (int i=0;i<threads.size();i++)
    {
      thread = (SearchThread)threads.get(i);
      node = new DefaultMutableTreeNode(thread);
      node.setUserObject(thread);
      root.add(node);
    }
    model = new DefaultTreeModel(root,true);
    return model;
  }

  class ExpandTree implements TreeExpansionListener
  {
    public void treeCollapsed(TreeExpansionEvent e)
    {
    }

    public void treeExpanded(TreeExpansionEvent e)
    {
      TreePath path = e.getPath();
      TreeNode node = (TreeNode)path.getLastPathComponent();
      if (node instanceof FtpFileNode)
      {
        DefaultTreeModel model = (DefaultTreeModel)resultTree.getModel();
        ((FtpFileNode)node).explore();
        model.nodeStructureChanged(node);
      }
    }
  }

  private void addResult(FtpSite site,FtpFile root,String welcome)
  {
    searchResults.add(new SearchResult(site,root));
    TreeModel model = resultTree.getModel();
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)model.getRoot();
    if (node ==null)
      return;
    DefaultMutableTreeNode siteNode = new DefaultMutableTreeNode(site);
    siteNode.setUserObject(site);
    siteNode.setAllowsChildren(true);
    node.add(siteNode);
    DefaultMutableTreeNode welcomeNode = new DefaultMutableTreeNode(
        "Welcome message");
    siteNode.add(welcomeNode);
    welcomeNode.add(new DefaultMutableTreeNode(welcome,false));
    FtpFileNode fileNode = new FtpFileNode(root);
    siteNode.add(fileNode);
    if (model instanceof DefaultTreeModel)
    {
      ((DefaultTreeModel)model).nodeStructureChanged(node);
    }
  }

  void updateThreadTree(SearchThread thread)
  {
    if (detailTree==null)
      return;
    DefaultTreeModel model = (DefaultTreeModel)detailTree.getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
    DefaultMutableTreeNode threadNode = null;
    DefaultMutableTreeNode findNode = null;
    SearchThread temp = null;
    Enumeration enu = root.children();
    while (enu.hasMoreElements())
    {
      threadNode = (DefaultMutableTreeNode)enu.nextElement();
      if (threadNode.getUserObject() instanceof SearchThread)
      {
        temp = (SearchThread)threadNode.getUserObject();
        if(temp==thread)
        {
          threadNode.removeAllChildren();
          findNode = new DefaultMutableTreeNode(
              thread.getCurrentSite(),false);
          threadNode.add(findNode);
          model.nodeStructureChanged(threadNode);
        }
      }
    }
  }

  /*
   save search results to xml file
   */
  public void save(String fileName)
  {
    starfire.gui.siteTree.TreeXmlSupport.saveSearchResult(
       (DefaultTreeModel)resultTree.getModel(),fileName);
  }

  public void load(String fileName)
  {

  }

  class SearchThread extends Thread
  {
    private int count = 0;
    private int find = 0;
    private InetAddress address ;
    private  FtpSite site;
    private  FtpClient client;
    private  FtpFile root = null;
    private int number = -1;
    private String welcomeMsg = null;

    public SearchThread(int number)
    {
      this.number = number;
      start();
      currentThreadLabel.setText("Thread "+number+" started");
    }

    public void cancel()
    {
      if (client!=null)
        client.disconnect();
     // stop = true;
    }

    public int getCount()
    {
      return count;
    }

    public int getFind()
    {
      return find;
    }

    public FtpSite getCurrentSite()
    {
      return site;
    }
    public void run()
    {
      String host;
      while (!stop)
      {
        address = SearchTaskManager.getManager().getNextAddress();
        if (address==null)
          break;
        count++;
        site = new FtpSite ();
        host = address.getHostAddress();
        site.setHost(host);
        client = new FtpClient(site);
        if (timeout>0)
          client.setTimeOut(timeout);
        if (login() && !stop)
        {
          System.out.println("find:"+host+":"+site.getPort());
          root = FtpFile.getDefaultRoot();
          addResult(site,root,welcomeMsg);
          updateThreadTree(this);
          find++;
          list(root);
          try
          {
            if (client!=null && client.isConnected())
              client.quit();
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      currentThreadLabel.setText("Thread "+number+" stopped");
    }

    private boolean login()
    {
      currentThreadLabel.setText("connect to "+site.getHost()+"...");
      if (!client.connect())
      {
        currentThreadLabel.setText("connect to "+site.getHost()+" failed");
        return false;
      }
      currentThreadLabel.setText(site.getHost()+":"+site.getPort()+" ok");
      try
      {
        welcomeMsg = client.readWelcomMsg();
       if (client.login() && !stop)
         return true;
       int size = users.size();
       int size1 = passwords.size();
       for (int i=0;i<size;i++)
       {
         for (int j=0;j<size1;j++)
         {
           if (!client.isConnected() && !reconnect())
             return false;
           site.setUser((String)users.get(i));
           site.setPassword((String)passwords.get(j));
           if (client.connect())
             return true;
         }
       }
      }catch (Exception e)
      {
        return false;
      }
      return false;
    }

    private boolean reconnect()
    {
      try
      {
        Thread.sleep(1000);
      }catch (Exception e)
      {
      }
      if (timeout!=-1)
        client.setTimeOut(timeout);
      if (client.connect() && !stop)
      {
        welcomeMsg = client.readWelcomMsg();
        return true;
      }
      else
        return false;
    }

    private void list(FtpFile f)
    {
      FtpFile ff = null;
      if (f.isFile())
        return ;
      Object[] objs = null;
      try
      {
        if (!client.isConnected())
        {
          try
          {
            Thread.sleep(3000);
          }catch (Exception e){}
          if (!login())
          {
            return;
          }
        }
        objs = client.listfiles(f.getPath());
        if (objs==null)
        {
          try
          {
            Thread.sleep(1000);
          }catch (Exception e){}
          return;
        }
        for (int i=0;i<objs.length && !stop;i++)
        {
          if (objs[i] instanceof FtpFile)
          {
            ff = (FtpFile)objs[i];
            if (ff.isDirectory())
              f.addChildren(ff);
          }
        }
        for (int i=0;i<objs.length && !stop;i++)
        {
          if (objs[i] instanceof FtpFile)
          {
            ff = (FtpFile)objs[i];
            if (ff.isFile())
              f.addChildren(ff);
          }
        }
        for (int i=0;i<objs.length && !stop;i++)
        {
          if (stop)
            return;
          if (objs[i] instanceof FtpFile)
          {
            ff = (FtpFile)objs[i];
            if (ff.isDirectory() && !stop)
            {
              try
              {
                Thread.sleep(200);
              }catch (Exception e){}
              list(ff);
            }
          }
        }
      }catch (Exception e)
      {
      }
    }

    public String toString()
    {
      return "thread "+number;
    }
  }

  class AutoSaveTask extends java.util.TimerTask
  {
    public void run()
    {
      if (autoSaveName==null)
      {
        autoSaveName = new String("searchResult_"+
                                  new Date().getTime()+".xml");
      }
      save(autoSaveName);
      System.out.println("result saved to "+autoSaveName);
    }
  }

  class CheckThread extends java.util.TimerTask
  {
    public void run()
    {
      Iterator iterator = threads.iterator();
      SearchThread thread;
      Object obj;
      int total = 0;
      int totalFind = 0;
      int aliveThread = 0;
      int totalThread = threads.size();
      while(iterator.hasNext())
      {
        obj = iterator.next();
        if (obj instanceof SearchThread)
        {
          thread = (SearchThread)obj;
          if (thread.isAlive())
            aliveThread++;
          total += thread.getCount();
          totalFind += thread.getFind();
        }
      }
      currentTime = System.currentTimeMillis();
      int hour,minute,second;
      int used = (int)(currentTime-startTime);
      second = used/1000%60;
      minute = used/1000/60%60;
      hour = used/1000/60/60%60;
      resultLabel.setText("Result:"+totalFind+"/"+total+
         "  spend "+hour+":"+minute+":"+second);
      threadLabel.setText("Thread:"+aliveThread+"/"+totalThread);
      if (aliveThread==0)
      {
        new Thread ()
        {
          public void run()
          {
              stopSearch();
              threadTimer.cancel();
          }
        }.start();
      }
    }
  }

  void onStop(ActionEvent e) {
    stopSearch();
  }

  void stopSearch()
  {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        stopAllThread();
      }
    });
    startButton.setEnabled(true);
    stopButton.setEnabled(false);
    stop = true;
    if (autoSaveTimer!=null)
      autoSaveTimer.cancel();
    autoSaveName = null;
    startIpField.setEditable(true);
    endIpField.setEditable(true);
    this.threadNumSpinner.setEnabled(true);
    this.timeoutSpinner.setEnabled(true);
    enableFind();
    loadButton.setEnabled(true);
  }

  void stopAllThread()
  {
    Iterator iterator = threads.iterator();
    SearchThread thread;
    Object obj;
    stop = true;
    while (iterator.hasNext())
    {
      obj = iterator.next();
      if (obj instanceof SearchThread)
      {
        thread = (SearchThread)obj;
        thread.cancel();
      }
    }
  }

  void onSave(ActionEvent e) {
   JFileChooser chooser = new JFileChooser();
   chooser.showSaveDialog(this);
   File f = chooser.getSelectedFile();
   if (f==null)
     return;
   autoSaveName = f.getPath();
   save(f.getPath());
  }

  void onLoad(ActionEvent e) {
    JFileChooser chooser = new JFileChooser();
    chooser.setFileFilter(new XMLFileFilter());
    chooser.showOpenDialog(this);
    final File f = chooser.getSelectedFile();
    if (f==null)
      return;
    currentThreadLabel.setText("loadding......");
    startButton.setEnabled(false);
    new Thread()
    {
      public void run() {
        load(f);
        currentThreadLabel.setText("");
        startButton.setEnabled(true);
      }
    }.start();
  }

  void load(File f)
  {
    TreeModel model = starfire.gui.siteTree.TreeXmlSupport.loadSearchResult(f);
    resultTree.setModel(model);
    enableFind();
    jScrollPane1.updateUI();
  }

  protected void finalized ()
  {
    resultTree = null;
    System.gc();
  }

  class XMLFileFilter extends javax.swing.filechooser.FileFilter
  {
    public boolean accept(File f)
    {
      if (f.isDirectory() || f.getName().toLowerCase().endsWith(".xml"))
        return true;
      return false;
    }

    public String getDescription()
    {
      return "xml file";
    }
  }

  void onFind(ActionEvent e) {
    new Thread()
    {
      public void run()
      {
        find();
      }
    }.start();
  }

  void find()
  {
    currentThreadLabel.setText("finding......");
    String find = findField.getText().trim();
    if (find.equals(""))
      return;
    TreeModel model = starfire.gui.siteTree.TreeXmlSupport.findFileFromTree(
       (DefaultTreeModel)resultTree.getModel(),find);
   detailTree.setModel(model);
   currentThreadLabel.setText("");
  }

  void findField_actionPerformed(ActionEvent e) {
    onFind(e);
  }

  void onDownload(ActionEvent e) {
    DefaultTreeModel model = (DefaultTreeModel)resultTree.getModel();
    if (model==null)
      return;
    starfire.manager.TaskManager manager = starfire.manager.TaskManager.getTaskManager();
    TreePath path = resultTree.getSelectionPath();
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
    Object obj = node.getUserObject();
    if (!(obj instanceof FtpFile)) {
      System.out.println("not a ftpfile,can't download!");
      return;
    }
    FtpFile ff = (FtpFile)obj;
    do {
      node = (DefaultMutableTreeNode)node.getParent();
      if (node.getUserObject() instanceof FtpSite) {
        break;
      }
    }while (node!=null);
    if (node==null) {
      System.out.println("can't find ftp site!!");
      return;
    }
    JTabbedPane tab = ftpFrame.getTabbedPane();
    DownloadManagerPanel dmp = (DownloadManagerPanel)
        tab.getComponentAt(tab.getTabCount() - 1);
    JPanel selectedPanel = (JPanel)tab.getSelectedComponent();
    String localePath = null;
    if (selectedPanel instanceof FtpMainPanel) {
      localePath = ((FtpMainPanel)selectedPanel).getCurrentLocaleDir().getPath();
    }
    else {
      File[] files = File.listRoots();
      for (int i=0;i<files.length;i++) {
        if (files[i].canWrite()) {
          localePath = files[i].getPath();
          break;
        }
      }
      if (localePath==null) {
        return;
      }
    }
    if (localePath.endsWith(File.separator)) {
      localePath += ff.getName();
    }
    else {
      localePath += File.separator+ff.getName();
    }
    FtpSite site = (FtpSite)node.getUserObject();
    FtpTaskDescription td = new FtpTaskDescription(site,ff);
    td.setLocalePath(localePath);
    FtpTask task = new FtpTask(td);
    manager.addTask(task);
    dmp.addTask(task);
    manager.autoDownload();
  }

  void resultTree_mouseClicked(MouseEvent e) {
    if (javax.swing.SwingUtilities.isRightMouseButton(e)) {
      popMenu.show(resultTree,e.getX(),e.getY());
    }
  }
}

class SearchResult
{
  FtpSite site;
  FtpFile root;

  public SearchResult(FtpSite site,FtpFile root)
  {
    this.site = site;
    this.root = root;
  }
}


class SearchTaskManager
{
  private InetAddress start = null,end = null,cur = null;
  private boolean hasSetted = false;
  private boolean noAddress = true;

  private static SearchTaskManager manager = new SearchTaskManager();

  public static SearchTaskManager getManager()
  {
    return manager;
  }

  private SearchTaskManager()
  {
  }

  public boolean set(String start,String end)
  {
   try
    {
      this.start = InetAddress.getByName(start);
      this.end = InetAddress.getByName(end);
      cur = this.start;
      hasSetted = true;
      noAddress = false;
    }catch (UnknownHostException e)
    {
      e.printStackTrace();
      hasSetted = false;
      return false;
    }
    return true;
  }

  public synchronized InetAddress getNextAddress()
  {
    if (noAddress==true || hasSetted==false)
      return null;
    if (cur.equals(end))
      noAddress = true;
    InetAddress temp = cur;
    byte[] bb = cur.getAddress();
    int ip =getIP(bb);
    cur =  getNextAddressByInt(ip);
    return temp;
  }

  private int getIP(byte[] b)
  {
    if (b==null)
      return 0;
    int ip = 0;
    for (int i=0;i<b.length;i++)
    {
      ip += ((int)(b[i]&0xff))<<((3-i)*8);
    }
    return ip;
  }

  private InetAddress getNextAddressByInt(int ip)
  {
    int p = ip+1;
    byte[] bb = new byte[4];
    for (int i=0;i<4;i++)
    {
      bb[i] = (byte)((p>>>((3-i)*8)&0xff));
    }
    try
    {
      InetAddress address = InetAddress.getByAddress(bb);
      return address;
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

class FtpSearchFrame_endIpField_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_endIpField_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.endIpField_actionPerformed(e);
  }
}

class FtpSearchFrame_startButton_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_startButton_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onStart(e);
  }
}

class FtpSearchFrame_stopButton_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_stopButton_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onStop(e);
  }
}

class FtpSearchFrame_saveButton_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_saveButton_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onSave(e);
  }
}

class FtpSearchFrame_loadButton_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_loadButton_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onLoad(e);
  }
}

class FtpSearchFrame_findButton_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_findButton_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onFind(e);
  }
}

class FtpSearchFrame_findField_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_findField_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.findField_actionPerformed(e);
  }
}

class FtpSearchFrame_downloadItem_actionAdapter implements java.awt.event.ActionListener {
  FtpSearchFrame adaptee;

  FtpSearchFrame_downloadItem_actionAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onDownload(e);
  }
}

class FtpSearchFrame_resultTree_mouseAdapter extends java.awt.event.MouseAdapter {
  FtpSearchFrame adaptee;

  FtpSearchFrame_resultTree_mouseAdapter(FtpSearchFrame adaptee) {
    this.adaptee = adaptee;
  }
  public void mouseClicked(MouseEvent e) {
    adaptee.resultTree_mouseClicked(e);
  }
}
